#include "A_Config.h"

WiFiManager WiFiMgr;

static String WiFiTable[WIFI_SAVE_MAX][2];
static uint16_t WiFiCount = 0;

void WiFiManager::save()
{
    File f = SPIFFS.open("/wifi.csv", "w");
    if (f)
    {
        for (uint16_t i = 0; i < WiFiCount; i++)
        {
            if (WiFiTable[i][0] != "" && WiFiTable[i][1].length() >= 8)
            {
                String s = WiFiTable[i][0] + "," + WiFiTable[i][1] + "\n";
                f.print(s);
            }
        }
        f.close();
    }
}

void WiFiManager::add(const String ssid, const String pass)
{
    for (uint16_t i = 0; i < WiFiCount; i++)
    {
        if (WiFiTable[i][0] == ssid)
        {
            WiFiTable[i][1] = pass;
            save();
            return;
        }
    }
    if (WiFiCount < WIFI_SAVE_MAX)
    {
        WiFiTable[WiFiCount][0] = ssid;
        WiFiTable[WiFiCount][1] = pass;
        ++WiFiCount;
        save();
    }
    return;
}

bool WiFiManager::has(const String ssid)
{
    for (uint16_t i = 0; i < WiFiCount; i++)
    {
        if (WiFiTable[i][0] == ssid)
        {
            return true;
        }
    }
    return false;
}

String WiFiManager::getPassword(const String ssid)
{
    for (uint16_t i = 0; i < WiFiCount; i++)
    {
        if (WiFiTable[i][0] == ssid)
        {
            return WiFiTable[i][1];
        }
    }
    return "";
}

static String errorreasons[] = {
    "空闲",
    "无可用SSID",
    "扫描结束",
    "已连接",
    "连接失败(可能是密码错误)",
    "连接丢失",
    "已断开连接",
};

bool WiFiManager::scanWiFiandConnect()
{
    char ssidtmp[70];
    char passtmp[70];
    bool donotsleepstat = hal.DoNotSleep;
    hal.DoNotSleep = true;
    hal.axpShortPress = false;
    lv_obj_t *msg = full_screen_msgbox_create(BIG_SYMBOL_SYNC, "WiFi扫描", "正在扫描WiFi，请稍候...");
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    int n = WiFi.scanNetworks();
    full_screen_msgbox_del(msg);
    if (n <= 0)
    {
        msgbox("提示", "周围没有WiFi网络", 3000);
        hal.DoNotSleep = donotsleepstat;
        return false;
    }
    menu_create();
    for (int i = 0; i < n; i++)
    {
        String s = WiFi.SSID(i);
        if (s == "")
            s = LV_SYMBOL_CLOSE " 隐藏的网络";
        else
        {
            if (WiFiMgr.has(s))
            {
                s = " " + s;
                s = LV_SYMBOL_SAVE + s;
            }
            else
            {
                s = " " + s;
                s = (WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? LV_SYMBOL_EYE_OPEN : LV_SYMBOL_SETTINGS + s;
            }
            s += ", ";
            s += WiFi.RSSI(i);
        }
        menu_add(s.c_str());
    }
    uint16_t sel = menu_show();
    if (sel == 0)
    {
        hal.DoNotSleep = donotsleepstat;
        return false;
    }
    sel -= 1;
    // 连接wifi
    String s = WiFi.SSID(sel);
    String pass;
    if (s == "")
        goto err;
    if (WiFi.encryptionType(sel) != WIFI_AUTH_OPEN)
    {
        if (WiFiMgr.has(s))
        {
            if (msgbox_yn("使用保存的密码？"))
            {
                pass = WiFiMgr.getPassword(s);
            }
            else
            {
                pass = msgbox_string("请输入密码");
                if (pass.length() < 8)
                {
                    msgbox(LV_SYMBOL_CLOSE " 错误", "密码不符合WPA标准要求，将使用之前保存的密码");
                    pass = WiFiMgr.getPassword(s);
                }
            }
        }
        else
        {
            pass = msgbox_string("请输入密码");
            if (pass.length() < 8)
            {
                msgbox(LV_SYMBOL_CLOSE " 错误", "密码不符合WPA标准要求，将返回上一个界面");
                goto err;
            }
        }
    }
    strcpy(ssidtmp, s.c_str());
    strcpy(passtmp, pass.c_str());
    if (WiFi.encryptionType(sel) == WIFI_AUTH_OPEN)
    {
        WiFi.scanDelete();
        WiFi.disconnect();
        WiFi.begin(ssidtmp);
    }
    else
    {
        WiFi.scanDelete();
        WiFi.disconnect();
        WiFi.begin(ssidtmp, passtmp);
    }
    vTaskDelay(100);
    msg = full_screen_msgbox_create(BIG_SYMBOL_WIFI, "连接中", "正在连接选择的WiFi");
    hal.DoNotSleep = true;
    hal.axpShortPress = false;
    vTaskDelay(300);
    for (uint16_t i = 0; i < 100; ++i)
    {
        if (WiFi.status() == WL_CONNECTED)
            break;
        if (hal.axpShortPress)
        {
            hal.axpShortPress = false;
            break;
        }
        vTaskDelay(100);
    }

    full_screen_msgbox_del(msg);
    vTaskDelay(100);
    if (WiFi.status() != WL_CONNECTED)
    {
        String m;
        m = "WiFi连接失败\n错误信息：\n";
        m += s;
        m += "\n";
        m += pass;
        m += "\n";
        m += errorreasons[WiFi.status()];
        full_screen_msgbox(BIG_SYMBOL_CROSS, "连接失败", m.c_str(), FULL_SCREEN_BG_CROSS);
        goto err;
    }

    hal.DoNotSleep = donotsleepstat;
    add(s, pass);
    return true;
err:
    hal.DoNotSleep = donotsleepstat;
    return false;
}

bool WiFiManager::connectGUI()
{
    lv_obj_t *msg;
start:
    WiFi.mode(WIFI_OFF);
    menu_create();
    menu_add(LV_SYMBOL_HOME " 使用学校WiFi");
    menu_add(LV_SYMBOL_OK " 使用上次选择的WiFi");
    menu_add(LV_SYMBOL_WIFI " 手动选择");
    menu_add(LV_SYMBOL_TRASH " 清除已保存网络");
    switch (menu_show())
    {
    case 0:
        WiFi.mode(WIFI_OFF);
        return false;
    case 1:
    {
        // 学校wifi
        msg = full_screen_msgbox_create(BIG_SYMBOL_WIFI, "连接中", "正在连接学校WiFi并自动认证");
        bool suc = schoolWiFi.connect();
        if (suc == false)
        {
            full_screen_msgbox_del(msg);
            full_screen_msgbox(BIG_SYMBOL_CROSS, "连接失败", "无法连接学校WiFi AP，将返回上一界面", FULL_SCREEN_BG_CROSS, 3000);
            goto start;
        }
        else
        {
            uint8_t succnt = 0;
            for (uint8_t i = 0; i < 8; ++i)
            {
                suc = schoolWiFi.authenticate();
                if (suc)
                    succnt++;
                if (succnt > 3 && suc == true)
                    break;
            }
            if (suc == false)
            {
                full_screen_msgbox_del(msg);
                full_screen_msgbox(BIG_SYMBOL_CROSS, "登录失败", "无法与校园网HTTP服务器认证，将返回上一界面", FULL_SCREEN_BG_CROSS, 3000);
                goto start;
            }
            else
            {
                full_screen_msgbox_del(msg);
                return true;
            }
        }
        break;
    }
    case 2:
    {
        // 上次选择的WiFi
        msg = full_screen_msgbox_create(BIG_SYMBOL_WIFI, "连接中", "正在连接上次选择的WiFi");
        WiFi.mode(WIFI_MODE_STA);
        WiFi.begin();
        hal.axpShortPress = false;
        for (uint16_t i = 0; i < 100; ++i)
        {
            if (WiFi.status() == WL_CONNECTED)
                break;
            if (hal.axpShortPress)
            {
                hal.axpShortPress = false;
                break;
            }
            vTaskDelay(100);
        }

        full_screen_msgbox_del(msg);
        if (WiFi.status() != WL_CONNECTED)
        {
            String m;
            m = "WiFi连接失败\n错误信息：\n";
            m += WiFi.SSID();
            m += "\n";
            m += WiFi.psk();
            m += "\n";
            m += errorreasons[WiFi.status()];
            full_screen_msgbox(BIG_SYMBOL_CROSS, "连接失败", m.c_str(), FULL_SCREEN_BG_CROSS, 3000);
            goto start;
        }
        else
        {
            return true;
        }
        break;
    }
    case 3:
    {
        if (scanWiFiandConnect())
        {
            return true;
        }
        else
        {
            goto start;
        }
        break;
    }
    case 4:
        if (msgbox_yn("是否确认清除已保存的网络？"))
        {
            clearall();
        }
        goto start;
        break;
    default:
        break;
    }
    WiFi.mode(WIFI_OFF);
    return false;
}

void WiFiManager::clearall()
{
    SPIFFS.remove("/wifi.csv");
    WiFiCount = 0;
    for (uint16_t i = 0; i < WIFI_SAVE_MAX; i++)
    {
        WiFiTable[i][0] = "";
        WiFiTable[i][1] = "";
    }
}

void WiFiManager::begin()
{
    WiFiCount = 0;
    for (uint16_t i = 0; i < WIFI_SAVE_MAX; i++)
    {
        WiFiTable[i][0] = "";
        WiFiTable[i][1] = "";
    }
    File f = SPIFFS.open("/wifi.csv", "r");
    if (f)
    {
        while (1)
        {
            String line = f.readStringUntil('\n');
            if (line != "")
            {
                WiFiTable[WiFiCount][0] = line.substring(0, line.indexOf(','));
                WiFiTable[WiFiCount][1] = line.substring(line.indexOf(',') + 1);
                WiFiTable[WiFiCount][1].replace("\n", "");
                ++WiFiCount;
            }
            else
                break;
        }
        f.close();
    }
    else
    {
        WiFiCount = 0;
        File f = SPIFFS.open("/wifi.csv", "w");
        if (f)
        {
            f.close();
        }
        else
        {
            Serial.println("Error: 无法写入文件wifi.csv");
        }
    }
}

bool WiFiManager::autoConnect()
{
    if (WiFi.status() != WL_CONNECTED)
    {
        bool sch = false;
        WiFi.begin();
        if (WiFi.psk() == SCHOOL_WIFI_PASSWD)
            sch = true;
        for (uint8_t i = 0; i < 10; ++i)
        {
            if (WiFi.status() == WL_CONNECTED)
                break;
            delay(100);
        }
        if (WiFi.status() == WL_CONNECTED)
        {
            if (sch)
            {
                uint8_t succnt = 0;
                bool suc;
                for (uint8_t i = 0; i < 8; ++i)
                {
                    suc = schoolWiFi.authenticate();
                    if (suc)
                        succnt++;
                    if (succnt > 3 && suc == true)
                        break;
                }
                if (suc == false)
                {
                    full_screen_msgbox(BIG_SYMBOL_CROSS, "登录失败", "无法与校园网HTTP服务器认证，将返回上一界面", FULL_SCREEN_BG_CROSS, 3000);
                    return connectGUI();
                }
                return true;
            }
            return true;
        }
        return connectGUI();
    }
    return true;
}